﻿using System;
using System.Text;
using System.Collections.Generic;
using System.Linq;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using SD = System.Diagnostics;
using CCC = CodeCamp.Controllers;
using e1 = CodeCamp.Entities01;
using e2 = CodeCamp.Entities02;
using e3 = CodeCamp.EFDAL;
using e3m = CodeCamp.Model;

namespace CodeCamp.Test.DataConversion
{
    [TestClass]
    public class OldDataTests : TestBase
    {
        private static class Tags
        {
            internal const string skipPresenterCopy = "skipPresenterCopy";
            internal const string skipSessionCopy = "skipSessionCopy";
        }

        [TestMethod]
        public void CanListOldEvents()
        {
            using (CCC.CodeCampDataRepository dr = new CCC.CodeCampDataRepository())
            {
                CCC.CodeCampDataRepositoryOld dro = new CCC.CodeCampDataRepositoryOld();

                IQueryable<e1.Event> oldEvents = dro.GetOldEvents();
                Assert.IsNotNull(oldEvents);
                TestContext.WriteLine("Old Events:");
                foreach (e1.Event ccevent in oldEvents)
                {
                    TestContext.WriteLine("{0}\t{1}\t\"{2}\"",
                        ccevent.Id,
                        ccevent.ShortName,
                        ccevent.DisplayName);
                }
            }
        }

        [TestMethod]
        public void CanListNewEvents()
        {
            using (CCC.CodeCampDataRepository dr = new CCC.CodeCampDataRepository())
            {
                List<e3m.Event> newEvents = dr.EFContext.Events.ToList();
                Assert.IsNotNull(newEvents);
                TestContext.WriteLine("New Events:");
                foreach (e3m.Event ccevent in newEvents)
                {
                    TestContext.WriteLine("{0}\t{1}\t\"{2}\"",
                        ccevent.Id,
                        ccevent.ShortName,
                        ccevent.DisplayName);
                }
            }
        }

        [TestMethod]
        public void CopyDataFromOldDbToNew()
        {
            SD.Debug.WriteLine("*** Start Old Data Copy");
            int oldDataErrors = 0;
            try
            {
                using (CCC.CodeCampDataRepository dr = new CCC.CodeCampDataRepository())
                {
                    CCC.CodeCampDataRepositoryOld dro = new CCC.CodeCampDataRepositoryOld();

                    //****************
                    // 1st Events Loop
                    //****************
                    SD.Debug.WriteLine("*** Copy Events:");
                    TestContext.WriteLine("Copy Events:");
                    IQueryable<e1.Event> oldEvents = dro.GetOldEvents();
                    int existingRootItems = 0;
                    int newlyCopiedRootItems = 0;
                    foreach (e1.Event oldEvent in oldEvents.OrderBy(e => e.Id))
                    {
                        e3m.Event newEvent = dr.EFContext.Events.Where(ne => ne.IdOld.HasValue && ne.IdOld == oldEvent.Id).FirstOrDefault();
                        if (newEvent != null)
                        {
                            existingRootItems++;
                        }
                        else
                        {
                            newEvent = new e3m.Event();
                            newEvent.IdOld = oldEvent.Id;
                            newEvent.ShortName = oldEvent.ShortName;
                            newEvent.DisplayName = oldEvent.DisplayName;
                            dr.EFContext.Events.Add(newEvent);
                            newlyCopiedRootItems++;
                            dr.EFContext.SaveChanges();
                        }
                    }
                    TestContext.WriteLine("Old events existing in new db: {0}.  Newly created in new db: {1}.",
                        existingRootItems,
                        newlyCopiedRootItems);

                    if ((existingRootItems == 0) && (newlyCopiedRootItems == 0))
                        Assert.Inconclusive("No existing or new events - nothing to do.");

                    //*****************
                    // Banned Tags Loop
                    //*****************
                    SD.Debug.WriteLine("*** Copy BannedTags:");
                    TestContext.WriteLine("Copy BannedTags:");
                    existingRootItems = 0;
                    newlyCopiedRootItems = 0;
                    IQueryable<e1.BannedTag> oldBannedTags = dro.GetOldBannedTags();
                    Assert.IsNotNull(oldBannedTags);
                    foreach (e1.BannedTag oldBannedTag in oldBannedTags)
                    {
                        e3m.BannedTag newBannedTag = dr.EFContext.BannedTags.Where(bt => bt.IdOld.HasValue && bt.IdOld == oldBannedTag.Id).FirstOrDefault();
                        if (newBannedTag != null)
                        {
                            existingRootItems++;
                        }
                        else
                        {
                            newBannedTag = new e3m.BannedTag()
                            {
                                IdOld = oldBannedTag.Id,
                                Name = oldBannedTag.Name
                            };
                            dr.EFContext.BannedTags.Add(newBannedTag);
                            dr.EFContext.SaveChanges();
                        }
                    }

                    TestContext.WriteLine("Old BannedTags existing in new db: {0}.  Newly created in new db: {1}.",
                        existingRootItems,
                        newlyCopiedRootItems);

                    //****************
                    // 2nd Events Loop
                    //****************
                    foreach (e1.Event oldEvent in oldEvents.OrderBy(e => e.Id))
                    {
                        e3m.Event newEvent = dr.EFContext.Events.Where(ne => ne.IdOld.HasValue && ne.IdOld == oldEvent.Id).FirstOrDefault();
                        Assert.IsNotNull(newEvent, "new event not found with old id = {0}", oldEvent.Id);

                        string msg = string.Format("*** Copying inner data for event {2} old Event Id = {0}, new Id = {1}...",
                            oldEvent.Id, newEvent.Id, newEvent.ShortName);
                        SD.Debug.WriteLine(msg);
                        TestContext.WriteLine(msg);

                        //*********************
                        // Sponsors loop
                        //*********************
                        int existingChildItems = 0;
                        int newlyCopiedChildItems = 0;
                        SD.Debug.WriteLine("***\tSponsors...");
                        TestContext.WriteLine("\tSponsors...");
                        IQueryable<e1.Sponsor> oldSponsors = dro.GetOldSponsors(oldEvent.Id);
                        Assert.IsNotNull(oldSponsors);
                        foreach (e1.Sponsor oldSponsor in oldSponsors.OrderBy(s => s.Id))
                        {
                            Assert.IsNotNull(newEvent.Sponsors);

                            e3m.Sponsor newSponsor = newEvent.Sponsors.Where(sp => sp.IdOld.HasValue && sp.IdOld == oldSponsor.Id).FirstOrDefault();
                            if (newSponsor != null)
                            {
                                existingChildItems++;
                            }
                            else
                            {
                                newSponsor = new e3m.Sponsor();
                                newSponsor.IdOld = oldSponsor.Id;
                                newSponsor.Event = newEvent;
                                newSponsor.ImageHeight = oldSponsor.ImageHeight;
                                newSponsor.ImageUrl = oldSponsor.ImageUrl;
                                newSponsor.ImageWidth = oldSponsor.ImageWidth;
                                newSponsor.Name = oldSponsor.Name;
                                newSponsor.Url = oldSponsor.Url;
                                newEvent.Sponsors.Add(newSponsor);
                                newlyCopiedChildItems++;
                                dr.EFContext.SaveChanges();
                            }
                        }

                        TestContext.WriteLine("\tOld sponsors existing in new db: {0}.  Newly created in new db: {1}.",
                            existingChildItems,
                            newlyCopiedChildItems);
                        //*** End of Sponsors loop ***

                        //************************
                        // CommunitySponsors loop
                        //************************
                        existingChildItems = 0;
                        newlyCopiedChildItems = 0;
                        SD.Debug.WriteLine("***\tCommunitySponsors...");
                        TestContext.WriteLine("\tCommunitySponsors...");
                        IQueryable<e1.CommunitySponsor> oldCSponsors = dro.GetOldCommunitySponsors(oldEvent.Id);
                        Assert.IsNotNull(oldCSponsors);
                        foreach (e1.CommunitySponsor oldSponsor in oldCSponsors.OrderBy(s => s.Id))
                        {
                            Assert.IsNotNull(newEvent.CommunitySponsors);
                            e3m.CommunitySponsor newSponsor = newEvent.CommunitySponsors.Where(cs => cs.IdOld.HasValue && cs.IdOld == oldSponsor.Id).FirstOrDefault();
                            if (newSponsor != null)
                            {
                                existingChildItems++;
                            }
                            else
                            {
                                newSponsor = new e3m.CommunitySponsor()
                                {
                                    IdOld = oldSponsor.Id,
                                    Name = oldSponsor.Name,
                                    Url = oldSponsor.Url,
                                    Event = newEvent
                                };
                                newEvent.CommunitySponsors.Add(newSponsor);
                                newlyCopiedChildItems++;
                                dr.EFContext.SaveChanges();
                            }
                        }

                        TestContext.WriteLine("\tOld CommunitySponsors existing in new db: {0}.  Newly created in new db: {1}.",
                            existingChildItems,
                            newlyCopiedChildItems);
                        //*** End of CommunitySponsors loop ***

                        //****************************
                        // IndividualContributors loop
                        //****************************
                        existingChildItems = 0;
                        newlyCopiedChildItems = 0;
                        SD.Debug.WriteLine("***\tIndividualContributors...");
                        TestContext.WriteLine("\tIndividualContributors...");
                        IQueryable<e1.IndividualContributor> oldIContribs = dro.GetOldIndividualContributors(oldEvent.Id);
                        Assert.IsNotNull(oldIContribs);
                        foreach (e1.IndividualContributor oldContrib in oldIContribs.OrderBy(c => c.Id))
                        {
                            Assert.IsNotNull(newEvent.IndividualContributors);
                            e3m.IndividualContributor newContrib = newEvent.IndividualContributors.Where(ic => ic.IdOld.HasValue && ic.IdOld == oldContrib.Id).FirstOrDefault();
                            if (newContrib != null)
                            {
                                existingChildItems++;
                            }
                            else
                            {
                                newContrib = new e3m.IndividualContributor()
                                {
                                    IdOld = oldContrib.Id,
                                    FirstName = oldContrib.FirstName,
                                    LastName = oldContrib.LastName,
                                    Event = newEvent
                                };
                                newEvent.IndividualContributors.Add(newContrib);
                                newlyCopiedChildItems++;
                                dr.EFContext.SaveChanges();
                            }
                        }

                        TestContext.WriteLine("\tOld contributors existing in new db: {0}.  Newly created in new db: {1}.",
                            existingChildItems,
                            newlyCopiedChildItems);
                        //*** End of IndividualContributors loop ***

                        //**********
                        // Tags loop
                        //**********
                        existingChildItems = 0;
                        newlyCopiedChildItems = 0;
                        SD.Debug.WriteLine("***\tTags...");
                        TestContext.WriteLine("\tTags (before other items that depend on them)...");
                        IQueryable<e1.Tag> oldTags = dro.GetOldTags(oldEvent.Id);
                        foreach (e1.Tag oldTag in oldTags.OrderBy(t => t.Id))
                        {
                            Assert.IsNotNull(newEvent.Tags);
                            e3m.Tag newTag = dr.EFContext.Tags.Where(t => t.Name == oldTag.Name).FirstOrDefault();
                            if (newTag != null)
                            {
                                existingChildItems++;
                            }
                            else
                            {
                                newTag = new e3m.Tag()
                                {
                                    IdOld = oldTag.Id,
                                    Event = newEvent,
                                    Name = oldTag.Name
                                };
                                newEvent.Tags.Add(newTag);
                                newlyCopiedChildItems++;
                                dr.EFContext.SaveChanges();
                            }
                        }

                        TestContext.WriteLine("\tOld tags existing in new db: {0}.  Newly created in new db: {1}.",
                            existingChildItems,
                            newlyCopiedChildItems);
                        // End of Tags loop

                        if (GetAppSettingBool(Tags.skipPresenterCopy, false))
                        {
                            TestContext.WriteLine("*** Skipping Presenter Copy ***");
                        }
                        else
                        {
                            //*********************
                            // Presenter Loop
                            //*********************
                            existingChildItems = 0;
                            newlyCopiedChildItems = 0;
                            SD.Debug.WriteLine("***\tPresenters...");
                            TestContext.WriteLine("\tPresenters...");
                            System.Data.Linq.EntitySet<e1.Presenter> oldPresenters = oldEvent.Presenters;
                            foreach (e1.Presenter oldPresenter in oldPresenters.OrderBy(p => p.Id))
                            {
                                Assert.IsNotNull(newEvent.Presenters);

                                e3m.Presenter newPresenter = newEvent.Presenters.Where(p => p.IdOld.HasValue && p.IdOld == oldPresenter.Id).FirstOrDefault();
                                if (newPresenter != null)
                                {
                                    existingChildItems++;
                                }
                                else
                                {
                                    newPresenter = new e3m.Presenter()
                                    {
                                        IdOld = oldPresenter.Id,
                                        Event = newEvent,
                                        BlogUrl = oldPresenter.BlogUrl,
                                        EmailAddress = oldPresenter.EmailAddress,
                                        FirstName = oldPresenter.FirstName,
                                        LastName = oldPresenter.LastName,
                                        ShirtSize = oldPresenter.ShirtSize,
                                        TwitterName = oldPresenter.TwitterName,
                                        UserIdentityClaimType = UserIdentityClaimType,
                                        UserIdentityIssuer = UserIdentityIssuer,
                                        UserIdentityProvider = UserIdentityProvider,
                                        UserIdentityClaim = oldPresenter.UserIdentityName,
                                        WebsiteUrl = oldPresenter.WebsiteUrl
                                    };
                                    newPresenter.SetUniqueUserIdentifier();

                                    if (!string.IsNullOrWhiteSpace(oldPresenter.Biography))
                                    {
                                        e3m.PresenterBiography bio = new e3m.PresenterBiography()
                                        {
                                            Content = oldPresenter.Biography,
                                            Presenter = newPresenter
                                        };
                                        newPresenter.PresenterBiographies.Add(bio);
                                    }

                                    //if (!string.IsNullOrWhiteSpace(oldPresenter.ShirtSize))
                                    //{
                                    //    e3m.ShirtSize newShirtSize = dr.DbContext.ShirtSizes.Where(ss => ss.Size == oldPresenter.ShirtSize).FirstOrDefault();
                                    //    if (newShirtSize != null)
                                    //        newPresenter.PresenterShirtSize = newShirtSize;
                                    //}

                                    newEvent.Presenters.Add(newPresenter);

                                    newlyCopiedChildItems++;
                                    dr.EFContext.SaveChanges();
                                }

                                if (GetAppSettingBool(Tags.skipSessionCopy, false))
                                {
                                    TestContext.WriteLine("*** Skipping Session Copy inside Presenter Copy ***");
                                }
                                else
                                {
                                    // ************
                                    // Session Loop
                                    // ************

                                    int existingGrandChildItems = 0;
                                    int newlyCopiedGrandChildItems = 0;
                                    foreach (e1.SessionPresenter oldSessionPresenter in oldPresenter.SessionPresenters.OrderBy(sp => sp.Id))
                                    {
                                        if (oldSessionPresenter.PresenterId != oldPresenter.Id)
                                        {
                                            TestContext.WriteLine("{0}\tSession Presenter Issue!!!!{0}\t\tPresenterId={1}, FirstName={2}, LastName={3} for presenter{0}\t\tPresenterId={4}, FirstName={5}, LastName={6} for presenter in SessionPresenter{0}{0}",
                                                Environment.NewLine,
                                                oldPresenter.Id,
                                                oldPresenter.FirstName,
                                                oldPresenter.LastName,
                                                oldSessionPresenter.PresenterId,
                                                oldSessionPresenter.Presenter.FirstName,
                                                oldSessionPresenter.Presenter.LastName
                                                );
                                            oldDataErrors++;
                                        }
                                        else
                                        {
                                            bool newSessionExists = false;
                                            e1.Session oldSession = oldSessionPresenter.Session;

                                            Assert.IsNotNull(newPresenter.SessionPresenters);

                                            e3m.SessionPresenter newSessionPresenter = newPresenter.SessionPresenters.Where(
                                                sp => sp.Session.IdOld.HasValue && sp.Session.IdOld == oldSession.Id).FirstOrDefault();

                                            e3m.Session newSession = null;
                                            if (newSessionPresenter != null)
                                            {
                                                newSession = newSessionPresenter.Session;
                                                newSessionExists = true;
                                            }

                                            if (newSession != null)
                                            {
                                                existingGrandChildItems++;
                                            }
                                            else
                                            {
                                                Assert.IsNotNull(newEvent.Sessions);

                                                newSession = newEvent.Sessions.Where(s => s.Title == oldSession.Title).FirstOrDefault();
                                                if (newSession != null)
                                                {
                                                    existingGrandChildItems++;
                                                    newSessionExists = true;
                                                }
                                                else
                                                {
                                                    newSession = new e3m.Session()
                                                    {
                                                        IdOld = oldSession.Id,
                                                        Description = oldSession.Description,
                                                        Event = newEvent,
                                                        SessionMaterialsUrl = oldSession.SessionMaterialsUrl,
                                                        Title = oldSession.Title
                                                    };
                                                    newlyCopiedGrandChildItems++;
                                                    newEvent.Sessions.Add(newSession);
                                                    dr.EFContext.SaveChanges();
                                                }
                                                bool skipAdditionOfSessionPresenter = false;
                                                if ((newSessionExists) && (newPresenter.Id != 0))
                                                {
                                                    e3m.SessionPresenter sessionPresenter4Check = newEvent.SessionPresenters.Where(
                                                        sp => sp.PresenterId == newPresenter.Id
                                                        && sp.SessionId == newSession.Id).FirstOrDefault();
                                                    if (sessionPresenter4Check != null)
                                                    {
                                                        skipAdditionOfSessionPresenter = true;
                                                        TestContext.WriteLine("{0}\t*** ERROR in OLD DATA ***{0}\tPresenter id={1}  {3} {4}{0}\tSession id={2} \"{5}\"{0}\t*** SessionPresenter exists ***{0}{0}",
                                                            Environment.NewLine,
                                                            newPresenter.Id,
                                                            newSession.Id,
                                                            newPresenter.FirstName,
                                                            newPresenter.LastName,
                                                            newSession.Title);
                                                        oldDataErrors++;
                                                    }
                                                }
                                                if (!skipAdditionOfSessionPresenter)
                                                {
                                                    newSessionPresenter = new e3m.SessionPresenter()
                                                    {
                                                        Presenter = newPresenter,
                                                        Session = newSession
                                                    };
                                                    newPresenter.SessionPresenters.Add(newSessionPresenter);
                                                    Assert.IsNotNull(newEvent.SessionPresenters);
                                                    newEvent.SessionPresenters.Add(newSessionPresenter);
                                                    dr.EFContext.SaveChanges();
                                                    ////Trigger save if session exists, but this is an additional presenter on the session
                                                    //if (newlyCopiedGrandChildItems == 0)
                                                    //    newlyCopiedGrandChildItems++;
                                                }
                                            }
                                            CopySessionTags(dr, oldSession, newEvent, newPresenter, newSession, ref oldDataErrors);
                                        }
                                    }
                                    if (Verbose) TestContext.WriteLine("\tOld sessions existing in new db: {0}.  Newly created in new db: {1} for presenter {2} {3} pid={4}.",
                                        existingGrandChildItems,
                                        newlyCopiedGrandChildItems,
                                        newPresenter.FirstName,
                                        newPresenter.LastName,
                                        newPresenter.Id);
                                }
                                //*** End of Presenter Loop ***
                            }

                            TestContext.WriteLine("\tOld presenters existing in new db: {0}.  Newly created in new db: {1}.",
                                existingChildItems,
                                newlyCopiedChildItems);
                        }

                        if (GetAppSettingBool(Tags.skipSessionCopy, false))
                        {
                            TestContext.WriteLine("*** Skipping 2nd Session Copy ***");
                        }
                        else
                        {
                            // ************
                            // Session Loop2
                            // ************

                            existingChildItems = 0;
                            newlyCopiedChildItems = 0;
                            SD.Debug.WriteLine("***\tSessions (2nd pass)...");
                            TestContext.WriteLine("\tSessions (2nd pass)...");
                            foreach (e1.Session oldSession in oldEvent.Sessions.OrderBy(s => s.Id))
                            {
                                e3m.Session newSession = newEvent.Sessions.Where(s => s.IdOld.HasValue && s.IdOld == oldSession.Id).FirstOrDefault();
                                if (newSession != null)
                                {
                                    existingChildItems++;
                                }
                                else
                                {
                                    if (oldSession.SessionPresenters.Count > 0)
                                    {
                                        TestContext.WriteLine("{0}\t*** Data Error -- old event id={1} session id={2} with presenter count={3} not found in new events.{0}\tTitle=\"{4}\"{0}{0}",
                                            Environment.NewLine,
                                            oldEvent.Id,
                                            oldSession.Id,
                                            oldSession.SessionPresenters.Count,
                                            oldSession.Title);
                                        oldDataErrors++;
                                    }
                                    else
                                    {
                                        newSession = new e3m.Session()
                                        {
                                            IdOld = oldSession.Id,
                                            Description = oldSession.Description,
                                            Event = newEvent,
                                            SessionMaterialsUrl = oldSession.SessionMaterialsUrl,
                                            Title = oldSession.Title
                                        };
                                        newEvent.Sessions.Add(newSession);
                                        dr.EFContext.SaveChanges();

                                        CopySessionTags(dr, oldSession, newEvent, null /*newPresenter*/, newSession, ref oldDataErrors);
                                    }
                                }
                            }
                            TestContext.WriteLine("\tOld sessions existing in new db: {0}.  Newly created in new db: {1}.",
                                existingChildItems,
                                newlyCopiedChildItems);
                            //*** end of Session Loop2 ***
                        }

                        //**************
                        // Timeslot Loop
                        //**************
                        existingChildItems = 0;
                        newlyCopiedChildItems = 0;
                        SD.Debug.WriteLine("***\tTimeslots...");
                        TestContext.WriteLine("\tTimeslots...");
                        IQueryable<e2.Timeslot> oldTimeslots = dro.GetOldTimeslots(oldEvent.Id);
                        foreach (e2.Timeslot oldTimeslot in oldTimeslots.OrderBy(t => t.Id))
                        {
                            Assert.IsNotNull(newEvent.Timeslots);

                            e3m.Timeslot newTimeslot = newEvent.Timeslots.Where(ts => ts.IdOld.HasValue && ts.IdOld == oldTimeslot.Id).FirstOrDefault();
                            if (newTimeslot != null)
                            {
                                existingChildItems++;
                            }
                            else
                            {
                                newTimeslot = new e3m.Timeslot()
                                {
                                    IdOld = oldTimeslot.Id,
                                    Event = newEvent,
                                    Date = oldTimeslot.Date,
                                    Name = oldTimeslot.Name,
                                    EndTime = oldTimeslot.EndTime,
                                    StartTime = oldTimeslot.StartTime
                                };
                                newEvent.Timeslots.Add(newTimeslot);
                                dr.EFContext.SaveChanges();
                                newlyCopiedChildItems++;
                            }
                        }
                        TestContext.WriteLine("\tOld timeslots existing in new db: {0}.  Newly created in new db: {1}.",
                            existingChildItems,
                            newlyCopiedChildItems);
                        //*** End of Timeslot Loop ***

                        //**************
                        // Building Loop
                        //**************
                        existingChildItems = 0;
                        newlyCopiedChildItems = 0;
                        SD.Debug.WriteLine("***\tBuildings...");
                        TestContext.WriteLine("\tBuildings...");
                        IQueryable<e2.Building> oldBuildings = dro.GetOldBuildings(oldEvent.Id);
                        foreach (e2.Building oldBuilding in oldBuildings.OrderBy(b => b.Id))
                        {
                            Assert.IsNotNull(newEvent.Buildings);

                            e3m.Building newBuilding = newEvent.Buildings.Where(b => b.IdOld.HasValue && b.IdOld == oldBuilding.Id).FirstOrDefault();

                            if (newBuilding != null)
                            {
                                existingChildItems++;
                            }
                            else
                            {
                                newBuilding = new e3m.Building()
                                {
                                    IdOld = oldBuilding.Id,
                                    Event = newEvent,
                                    Name = oldBuilding.Name
                                };
                                newEvent.Buildings.Add(newBuilding);
                                newlyCopiedChildItems++;
                                dr.EFContext.SaveChanges();
                            }

                            //**********
                            // Room Loop
                            //**********
                            int existingGrandChildItems = 0;
                            int newlyCopiedGrandChildItems = 0;
                            foreach (e2.Room oldRoom in oldBuilding.Rooms.OrderBy(r => r.Id))
                            {
                                Assert.IsNotNull(newBuilding.Rooms);
                                e3m.Room newRoom = newBuilding.Rooms.Where(r => r.IdOld.HasValue && r.IdOld == oldRoom.Id).FirstOrDefault();
                                if (newRoom != null)
                                {
                                    existingChildItems++;
                                }
                                else
                                {
                                    newRoom = new e3m.Room()
                                    {
                                        IdOld = oldRoom.Id,
                                        Building = newBuilding,
                                        Name = oldRoom.Name
                                    };
                                    newBuilding.Rooms.Add(newRoom);
                                    newlyCopiedGrandChildItems++;
                                    dr.EFContext.SaveChanges();
                                }

                                //*********************************
                                // Scheduled Session Loop (in Room)
                                //*********************************
                                int existingGreatGrandChildItems = 0;
                                int newlyCopiedGreatGrandChildItems = 0;
                                foreach (e2.ScheduledSession oldSchedSession in oldRoom.ScheduledSessions.OrderBy(ss => ss.Id))
                                {
                                    Assert.IsNotNull(newRoom.ScheduledSessions);
                                    e3m.ScheduledSession newSchedSession = newRoom.ScheduledSessions.Where(ss => ss.IdOld.HasValue && ss.IdOld == oldSchedSession.Id).FirstOrDefault();
                                    if (newSchedSession != null)
                                    {
                                        existingGreatGrandChildItems++;
                                    }
                                    else
                                    {
                                        bool badOldData = false;
                                        e3m.Session newSession = newEvent.Sessions.Where(s => s.IdOld.HasValue && s.IdOld == oldSchedSession.SessionId).FirstOrDefault();
                                        if (newSession == null)
                                        {
                                            badOldData = true;
                                            TestContext.WriteLine("{0}\t*** ERROR copying old data - matching new session not found{0}\tOld event id={1} \"{3}\", room id={4} \"{6}\", schedSession id={7} SessionID={8}{0}\tNew event id={2}, room id={5}{0}{0}",
                                                Environment.NewLine,
                                                oldEvent.Id,
                                                newEvent.Id,
                                                oldEvent.ShortName,
                                                oldRoom.Id,
                                                newRoom.Id,
                                                oldRoom.Name,
                                                oldSchedSession.Id,
                                                oldSchedSession.SessionId);
                                            oldDataErrors++;
                                        }
                                        e3m.Timeslot newTimeslot = newEvent.Timeslots.Where(ts => ts.IdOld.HasValue && ts.IdOld == oldSchedSession.TimeslotId).FirstOrDefault();
                                        if (newTimeslot == null)
                                        {
                                            badOldData = true;
                                            TestContext.WriteLine("{0}\t*** ERROR copying old data - matching new timeslot not found{0}\tOld event id={1} \"{3}\", room id={4} \"{6}\", schedSession id={7} TimeslotId={8}{0}\tNew event id={2}, room id={5}{0}{0}",
                                                Environment.NewLine,
                                                oldEvent.Id,
                                                newEvent.Id,
                                                oldEvent.ShortName,
                                                oldRoom.Id,
                                                newRoom.Id,
                                                oldRoom.Name,
                                                oldSchedSession.Id,
                                                oldSchedSession.TimeslotId);
                                            oldDataErrors++;
                                        }

                                        if (!badOldData)
                                        {
                                            newSchedSession = new e3m.ScheduledSession()
                                            {
                                                IdOld = oldSchedSession.Id,
                                                Room = newRoom,
                                                Session = newSession,
                                                Timeslot = newTimeslot
                                            };
                                            newRoom.ScheduledSessions.Add(newSchedSession);
                                            dr.EFContext.SaveChanges();
                                        }
                                    }
                                }
                                if ((Verbose) && (newlyCopiedGreatGrandChildItems > 0))
                                {
                                    TestContext.WriteLine("\t\t\tOld sched session existing in new db: {0}.  Newly created in new db: {1} for Room id={2} {3}.",
                                        existingGreatGrandChildItems,
                                        newlyCopiedGreatGrandChildItems,
                                        newRoom.Id,
                                        newRoom.Name);
                                }
                                //*** End of Scheduled Session Loop (in Room) ***
                            }
                            //if (newlyCopiedGrandChildItems > 0)
                            {
                                TestContext.WriteLine("\t\tOld rooms existing in new db: {0}.  Newly created in new db: {1} for Building id={2} {3}.",
                                    existingGrandChildItems,
                                    newlyCopiedGrandChildItems,
                                    newBuilding.Id,
                                    newBuilding.Name);
                            }
                            //*** End of Room Loop ***
                        }
                        TestContext.WriteLine("\tOld buildings existing in new db: {0}.  Newly created in new db: {1}.",
                            existingChildItems,
                            newlyCopiedChildItems);

                        //*** End of Building Loop ***
                    }
                    //*** End of Events Loop ***
                }
            }
            catch (System.Data.Entity.Validation.DbEntityValidationException ex)
            {
                ReportException(ex);
                throw;
            }
            Assert.AreEqual(0, oldDataErrors, "*** Found {0} errors in old data ***", oldDataErrors);

        }

        //********************************************************************************
        private void CopySessionTags(CCC.CodeCampDataRepository dr, e1.Session oldSession, 
            e3m.Event newEvent, e3m.Presenter newPresenter, e3m.Session newSession, ref int oldDataErrors)
        {
            //**** Tags in session
            int existingGreatGrandChildItems = 0;
            int newlyCopiedGreatGrandChildItems = 0;
            List<e1.SessionTag> oldSessionTags = oldSession.SessionTags.ToList();
            Assert.IsNotNull(oldSessionTags);
            foreach (e1.SessionTag oldSessionTag in oldSessionTags.OrderBy(st => st.Id))
            {
                Assert.IsNotNull(newSession.SessionTags);
                e3m.SessionTag newSessionTag = newSession.SessionTags.Where(st => st.IdOld.HasValue && st.IdOld == oldSessionTag.Id).FirstOrDefault();
                if (newSessionTag != null)
                {
                    existingGreatGrandChildItems++;
                }
                else
                {
                    //Try again using tag text (check for data error in old data)
                    newSessionTag = newSession.SessionTags.Where(st => st.Tag.Name == oldSessionTag.Tag.Name).FirstOrDefault();
                    if (newSessionTag != null)
                    {
                        TestContext.WriteLine("{0}\t*** ERROR in OLD DATA ***{0}\tPresenter id={1}  {3} {4}{0}\tSession id={2} \"{5}\"{0}\tOld: Session.Id={6}, .SessionTag.Id={7}, .Tag.Id={8} \"{9}\"{0}\t*** Session Tag exists ***{0}{0}",
                            Environment.NewLine,
                            (newPresenter != null) ? newPresenter.Id : 0,
                            newSession.Id,
                            (newPresenter != null) ? newPresenter.FirstName : "n/a",
                            (newPresenter != null) ? newPresenter.LastName : "n/a",
                            newSession.Title,
                            oldSession.Id,
                            oldSessionTag.Id,
                            oldSessionTag.Tag.Id,
                            oldSessionTag.Tag.Name);
                        oldDataErrors++;
                    }
                    else
                    {
                        Assert.IsNotNull(newEvent.Tags);
                        e3m.Tag newTag = newEvent.Tags.Where(t => t.IdOld.HasValue && t.IdOld == oldSessionTag.Tag.Id).FirstOrDefault();
                        if (newTag == null)
                        {
                            newTag = new e3m.Tag()
                            {
                                IdOld = oldSessionTag.Tag.Id,
                                Event = newEvent,
                                Name = oldSessionTag.Tag.Name
                            };
                            newEvent.Tags.Add(newTag);
                            dr.EFContext.SaveChanges();
                        }
                        newSessionTag = new e3m.SessionTag()
                        {
                            IdOld = oldSessionTag.Id,
                            Tag = newTag,
                            Session = newSession
                        };
                        newSession.SessionTags.Add(newSessionTag);
                        newlyCopiedGreatGrandChildItems++;
                        dr.EFContext.SaveChanges();
                    }
                }
                if (Verbose && (newlyCopiedGreatGrandChildItems > 0))
                {
                    TestContext.WriteLine("\t\tOld Session tags existing in new db: {0}.  Newly created in new db: {1} for presenter id={2}, session id={3} \"{4}\".",
                        existingGreatGrandChildItems,
                        newlyCopiedGreatGrandChildItems,
                        (newPresenter != null) ? newPresenter.Id : 0,
                        newSession.Id,
                        ((newSession.Title.Length > 24) ? newSession.Title.Substring(0, 24) : newSession.Title));
                }
            }
        }

    }
}
